package com.usian.listener;

import com.rabbitmq.client.Channel;
import com.usian.mapper.DeDuplicationMapper;
import com.usian.pojo.DeDuplication;
import com.usian.pojo.LocalMessage;
import com.usian.service.ItemService;
import com.usian.utils.JsonUtils;
import org.springframework.amqp.core.ExchangeTypes;
import org.springframework.amqp.core.Message;
import org.springframework.amqp.rabbit.annotation.Exchange;
import org.springframework.amqp.rabbit.annotation.Queue;
import org.springframework.amqp.rabbit.annotation.QueueBinding;
import org.springframework.amqp.rabbit.annotation.RabbitListener;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.util.Date;

@Component //交给spring管理
public class OrderAddListener {

    @Autowired
    private ItemService itemService;

    @Autowired
    private DeDuplicationMapper deDuplicationMapper;

    /**
     * 监听者接收消息三要素：
     *  1、queue
     *  2、exchange
     *  3、routing key
     */
    @RabbitListener(bindings = @QueueBinding(value = @Queue(value="item_queue",durable = "true"),
            exchange = @Exchange(value="order_exchange",
            type= ExchangeTypes.TOPIC),
            key= {"order.add"}
    ))
    public void listener(String msg, Channel channel, Message message){
        try {
        //查询订单是否被消费
        //先将消息转化为对象
        LocalMessage localMessage = JsonUtils.jsonToPojo(msg, LocalMessage.class);
        String txNo = localMessage.getTxNo();
        DeDuplication deDuplication = deDuplicationMapper.selectByPrimaryKey(txNo);

        if (deDuplication == null) {

            //订单id
            Integer result = itemService.updateDelTbItemByOrderId(localMessage.getOrderNo());
            if(!(result>0)){
                throw new RuntimeException("扣减失败");
            }

            //消息被消费完 必须被记录
            DeDuplication d = new DeDuplication();
            d.setTxNo(txNo);
            d.setCreateTime(new Date());
            deDuplicationMapper.insert(d);

        }else {
            System.out.println("=======幂等生效：事务"+deDuplication.getTxNo() +" 已成功执行===========");
        }
             //ack 告诉mq消息已经被消费成功
            channel.basicAck(message.getMessageProperties().getDeliveryTag(),false);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}
